tg-me.com/golang_books/971
Last Update:
🛠 Создание собственного ResponseWriter: безопасный HTTP в Go
*Автор: Антонио Питаси*
*Источник: [anto.pt](https://anto.pt/articles/go-http-responsewriter)*
📌 Основная идея
В Go интерфейс http.ResponseWriter
напрямую записывает данные в сокет, что может приводить к незаметным ошибкам:
• Забывание установки кода состояния ответа.
• Попытка изменить заголовки после начала записи (это не вызовет ошибок, но и не сработает).
• Продолжение выполнения обработчика даже после ошибок, что может повлиять на корректность ответа.
➡ Решение: создать собственную обёртку для ResponseWriter
, чтобы добавить проверки и сделать обработку HTTP-запросов более безопасной и предсказуемой.
⚠️ Проблемы стандартного ResponseWriter
1️⃣ Автоматическая установка кода состояния:
Go сам устанавливает код 200 OK при первом вызове Write()
, если вы забыли явно вызвать WriteHeader()
. Это скрывает ошибки.
2️⃣ Изменение заголовков после начала записи:
После начала отправки тела ответа заголовки нельзя изменить. Go не сигнализирует об этом явно.
3️⃣ Выполнение после ошибок:
Обработчик продолжает выполнение даже после отправки ошибки, если вы забыли поставить return
.
## 🧱 Пример реализации обёртки
type HttpWriter struct {
w http.ResponseWriter
headerWritten bool
statusCode int
}
func NewHttpWriter(w http.ResponseWriter) http.ResponseWriter {
return &HttpWriter{w: w}
}
func (w *HttpWriter) Header() http.Header {
return w.w.Header()
}
func (w *HttpWriter) WriteHeader(statusCode int) {
w.w.WriteHeader(statusCode)
w.headerWritten = true
w.statusCode = statusCode
}
func (w *HttpWriter) Write(data []byte) (int, error) {
if !w.headerWritten {
log.Println("⚠️ Предупреждение: Write() вызван без предварительного WriteHeader()")
}
if w.statusCode >= 500 {
log.Println("⚠️ Статус 500: запись игнорируется")
return 0, nil
}
return w.w.Write(data)
}
## 🔄 Интеграция через middleware
Чтобы все обработчики автоматически использовали новый
HttpWriter
, можно внедрить его через middleware:
func middleware(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
writer := NewHttpWriter(w)
h.ServeHTTP(writer, r)
})
}
✅ Преимущества
• Явное требование установки кода состояния.
• Логирование попыток записи без
WriteHeader()
. • Блокировка записи при статусах >=500 для предотвращения некорректного ответа.
• Улучшенная предсказуемость и безопасность обработки HTTP-запросов.
🔗 Подробнее в оригинальной статье
BY Golang Books

Share with your friend now:
tg-me.com/golang_books/971